﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using ControleRepresentante.Logic.ImpostoHandlers;

namespace ControleRepresentante.Logic.Models
{
    public class Pedido : AttributeHolder
    {
        private readonly IList<Produto> m_Produtos;
        private readonly IList<Post> m_Posts;
        private string m_ClienteNome;
        private string m_VendedorNome;
        private string m_FabricaNome;
        private string m_TransportadoraNome;

        public Pedido()
        {
            m_Produtos = new List<Produto>();
            Data = DateTime.Today;
            m_Posts = new List<Post>();
        }

        public virtual int Numero { get; protected set; }
        public virtual IEnumerable<Post> Posts { get { return m_Posts; } }
        public virtual Cliente Cliente { get; set; }
        public virtual Vendedor Vendedor { get; set; }
        public virtual Fabrica Fabrica { get; set; }
        public virtual Transportadora Transportadora { get; set; }
        [Required(ErrorMessage = "*")]
        public virtual DateTime Data { get; set; }
        public virtual string CondicaoPagamento { get; set; }
        public virtual string PrazoEntrega { get; set; }
        public virtual string Observacao { get; set; }
        public virtual IEnumerable<Produto> Produtos { get { return m_Produtos; } }
        public virtual bool Faturado { get; set; }
        public virtual bool Cancelado { get; set; }
        public virtual double TotalMercadoria { get; set; }
        public virtual double ValorImposto { get; set; }
        public virtual double TotalLiquido { get; set; }
        public virtual double ValorDesconto { get { return TotalMercadoria * Desconto / 100; } }
        public virtual int TotalPecas { get; set; } 
        public virtual string ClienteNome
        {
            get { return m_ClienteNome ?? (m_ClienteNome = Cliente.RazaoSocial); }
            set { m_ClienteNome = value; }
        }
        public virtual string VendedorNome
        {
            get { return m_VendedorNome ?? (m_VendedorNome = Vendedor.Nome); }
            set { m_VendedorNome = value; }
        }
        public virtual string FabricaNome
        {
            get { return m_FabricaNome ?? (m_FabricaNome = Fabrica.Nome); }
            set { m_FabricaNome = value; }
        }
        public virtual string TransportadoraNome
        {
            get { return m_TransportadoraNome ?? (m_TransportadoraNome = Transportadora.Nome); }
            set { m_TransportadoraNome = value; }
        }
        public virtual PedidoJolitex PedidoJolitex { get; protected set; }
        public virtual double Desconto { get; set; }
        public virtual DateTime Created { get; set; }
        public virtual DateTime Modified { get; set; }

        public virtual void SetPedidoJolitex()
        {
            PedidoJolitex = new PedidoJolitex(this);
        }

        public virtual void AddProduto(Produto produto)
        {
            produto.Pedido = this;
            m_Produtos.Add(produto);
        }

        public virtual void RemoveProduto(Produto produto)
        {
            produto.Pedido = null;
            m_Produtos.Remove(produto);
        }

        public virtual void AddPost(Post post)
        {
            post.Pedido = this;
            m_Posts.Add(post);
        }

        public virtual void RemovePost(Post post)
        {
            post.Pedido = null;
            m_Posts.Remove(post);
        }

        public virtual void ClearPosts()
        {
            foreach (Post post in Posts.ToArray())
            {
                RemovePost(post);
                post.User = null;
            }
        }

        public virtual bool ManualCalculatedValues { get; set; }

        public virtual void SetCalculatedValues(IImpostoProvider impostoProvider)
        {
            TotalPecas = Produtos.Sum(x => x.Quantidade);
            if (!ManualCalculatedValues)
            {
                TotalMercadoria = Produtos.Sum(x => x.Quantidade*x.PrecoUnitario);
                ValorImposto = impostoProvider.Evaluate(Representante, this);
                TotalLiquido = TotalMercadoria - ValorDesconto + ValorImposto;
            }
        }
    }

    public class PedidoJolitex : ModelBase
    {
        internal PedidoJolitex(Pedido pedido)
        {
            Pedido = pedido;
        }

        protected PedidoJolitex()
        {
        }

        public virtual bool Sincronizado { get; set; }
        public virtual string Codigo { get; set; }
        protected virtual internal Pedido Pedido { get; protected set; }

        public override Guid Id
        {
            get { return Pedido.Id; }
            set { }
        }
    }
}
